package com.bf.electroplating.controller;

import com.bf.electroplating.pojo.dto.MessageDTO;
import com.bf.electroplating.pojo.vo.equipment.ClientVo;
import com.bf.electroplating.pojo.vo.equipment.ConnectedClientVo;
import com.bf.electroplating.service.compoent.HJ212ClientManager;
import com.bf.electroplating.pojo.vo.ResultVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * HJ212客户端管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/hj212/client")
@Tag(name = "HJ212客户端管理", description = "HJ212客户端连接管理接口")
public class HJ212ClientController {
    
    @Autowired
    private HJ212ClientManager clientManager;
    
    @PostMapping("/create")
    @Operation(summary = "创建客户端连接", description = "创建并连接到HJ212服务器的客户端")
    public ResultVO<String> createClient(
            @Parameter(description = "客户端ID") @RequestParam String clientId,
            @Parameter(description = "服务器地址") @RequestParam(defaultValue = "localhost") String host,
            @Parameter(description = "服务器端口") @RequestParam(defaultValue = "8103") int port) {
        try {
            boolean success = clientManager.createClient(clientId, host, port);
            if (success) {
                return ResultVO.ok("客户端连接创建成功");
            } else {
                return ResultVO.fail("客户端连接创建失败");
            }
        } catch (Exception e) {
            log.error("创建客户端连接失败", e);
            return ResultVO.fail("创建客户端连接失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/create/test")
    @Operation(summary = "创建测试客户端", description = "创建指定数量的测试客户端连接")
    public ResultVO<String> createTestClients(
            @Parameter(description = "客户端数量") @RequestParam(defaultValue = "3") int count) {
        try {
            int successCount = clientManager.createTestClients(count);
            return ResultVO.ok("创建测试客户端完成，成功: " + successCount + "/" + count);
        } catch (Exception e) {
            log.error("创建测试客户端失败", e);
            return ResultVO.fail("创建测试客户端失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/send")
    @Operation(summary = "发送消息给客户端", description = "向指定的客户端发送消息")
    public ResultVO<String> sendMessageToClient( @Validated  @RequestBody MessageDTO dto ) {
        try {
            boolean success = clientManager.sendMessage(dto.getClientId (), dto.getMessage ());
            if (success) {
                return ResultVO.ok("消息发送成功");
            } else {
                return ResultVO.fail("消息发送失败，客户端可能不存在或已断开连接");
            }
        } catch (Exception e) {
            log.error("发送消息失败", e);
            return ResultVO.fail("发送消息失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/{clientId}/send/test")
    @Operation(summary = "发送测试数据包", description = "向指定的客户端发送标准HJ212测试数据包")
    public ResultVO<String> sendTestPacket(
            @Parameter(description = "客户端ID") @PathVariable String clientId) {
        try {
            boolean success = clientManager.sendTestPacket(clientId);
            if (success) {
                return ResultVO.ok("测试数据包发送成功");
            } else {
                return ResultVO.fail("测试数据包发送失败，客户端可能不存在或已断开连接");
            }
        } catch (Exception e) {
            log.error("发送测试数据包失败", e);
            return ResultVO.fail("发送测试数据包失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/send/test/all")
    @Operation(summary = "向所有客户端发送测试数据包", description = "向所有连接的客户端发送标准HJ212测试数据包")
    public ResultVO<String> sendTestPacketToAll() {
        try {
            int successCount = clientManager.sendTestPacketToAll();
            return ResultVO.ok("测试数据包发送完成，成功发送给 " + successCount + " 个客户端");
        } catch (Exception e) {
            log.error("向所有客户端发送测试数据包失败", e);
            return ResultVO.fail("向所有客户端发送测试数据包失败: " + e.getMessage());
        }
    }
    
    @DeleteMapping("/{clientId}")
    @Operation(summary = "断开客户端连接", description = "断开指定客户端的连接")
    public ResultVO<String> disconnectClient(
            @Parameter(description = "客户端ID") @PathVariable String clientId) {
        try {
            boolean success = clientManager.disconnectClient(clientId);
            if (success) {
                return ResultVO.ok("客户端连接已断开");
            } else {
                return ResultVO.fail("断开连接失败，客户端可能不存在");
            }
        } catch (Exception e) {
            log.error("断开客户端连接失败", e);
            return ResultVO.fail("断开客户端连接失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/list")
    @Operation(summary = "获取客户端列表", description = "获取当前所有客户端连接信息")
    public ResultVO<ConnectedClientVo> getClientList() {
        try {
            ConcurrentHashMap<String, SocketChannel> clients = clientManager.getClientConnections ();
            int clientCount = clientManager.getClientCount();
            // 将客户端信息转换为ClientVo集合
            List < ClientVo > clientVoList = clients.entrySet().stream()
                    .map(entry -> {
                        ClientVo clientVo = new ClientVo();
                        clientVo.setClientId(entry.getKey());
                        clientVo.setAddress ( entry.getValue ().toString () );
                        return clientVo;
                    })
                    .toList();
            ConnectedClientVo vo = new ConnectedClientVo ();
            vo.setCount ( clientCount );
            vo.setClientVo ( clientVoList );
            
            return ResultVO.ok(vo);
        } catch (Exception e) {
            log.error("获取客户端列表失败", e);
            return ResultVO.fail("获取客户端列表失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/count")
    @Operation(summary = "获取客户端数量", description = "获取当前连接的客户端数量")
    public ResultVO<Integer> getClientCount() {
        try {
            int count = clientManager.getClientCount();
            return ResultVO.ok(count);
        } catch (Exception e) {
            log.error("获取客户端数量失败", e);
            return ResultVO.fail("获取客户端数量失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/{clientId}/status")
    @Operation(summary = "检查客户端连接状态", description = "检查指定客户端是否已连接")
    public ResultVO<Boolean> isClientConnected(
            @Parameter(description = "客户端ID") @PathVariable String clientId) {
        try {
            boolean isConnected = clientManager.isClientConnected(clientId);
            return ResultVO.ok(isConnected);
        } catch (Exception e) {
            log.error("检查客户端连接状态失败", e);
            return ResultVO.fail("检查客户端连接状态失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/cleanup")
    @Operation(summary = "清理所有客户端连接", description = "断开所有客户端连接")
    public ResultVO<String> cleanupAllClients() {
        try {
            clientManager.cleanup();
            return ResultVO.ok("所有客户端连接已清理");
        } catch (Exception e) {
            log.error("清理客户端连接失败", e);
            return ResultVO.fail("清理客户端连接失败: " + e.getMessage());
        }
    }
} 